#ifndef CBASERECEIVERMODULE_H_INCLUDED
#define CBASERECEIVERMODULE_H_INCLUDED

#include <irrlicht.h>


namespace irr
{


        // Класс бысрого рецейвера, выполняющий основные громоздкие, но необходимые операции
        // с пользовательским вводом, к тому же постоянно повторяемые.
        struct CBaseReceiverModule : public irr::IEventReceiver
        {
            /// состояния клвиатуры и мыши
            bool is_kStates[KEY_KEY_CODES_COUNT];
            bool is_mStates[EMIE_COUNT];

        /// дополнительные необходимые данные о мыши
            f32 mX,mY,
            //^ Стартовая позиция щелчка мыши
            draggX, draggY;
            //^ trans от translete: смещение = смещение при зажатой кнопке мыши
            SEvent * events;



        /// Конструктор. Параметров нет.
            CBaseReceiverModule()
            {
                mX=mY=draggX=draggY = 0;
                events = 0;

            /// Инициировать массив статусов
                for ( u32 i=0; i<KEY_KEY_CODES_COUNT; ++i )
                    is_kStates[i] = false;

                for ( u32 i=0; i<EMIE_COUNT; ++i )
                    is_mStates[i] = false;
            }

            virtual ~CBaseReceiverModule() { }



            /// основные, часто повторяемые действия
            virtual bool OnEvent( const SEvent & _event_ )
            {
                events = const_cast<SEvent*>(&_event_);

                // просто запоминаем состояние любой клавиши и состояния мыши
                if ( _event_.EventType == irr::EET_KEY_INPUT_EVENT )
                    is_kStates[_event_.KeyInput.Key] = _event_.KeyInput.PressedDown;

                 if(_event_.EventType == irr::EET_MOUSE_INPUT_EVENT)
                 // {
                    for( s32 i=0; i<EMIE_COUNT; ++i )
                        is_mStates[i] = i == _event_.MouseInput.Event;

                     /// стартовая позиция щелчка мыши
                     if( is_mStates[EMIE_LMOUSE_PRESSED_DOWN] || is_mStates[EMIE_RMOUSE_PRESSED_DOWN] )
                     {
                        mX = _event_.MouseInput.X;
                        mY = _event_.MouseInput.Y;
                     }

                     /// от стартовой позиции рассчитываем смещение
                     if ( _event_.MouseInput.isLeftPressed() || _event_.MouseInput.isRightPressed() )
                            // смещение при зажатой левой кнопке мыши
                            if ( is_mStates[EMIE_MOUSE_MOVED] )
                            {
                                draggX = mX - _event_.MouseInput.X;
                                draggY = mY - _event_.MouseInput.Y;
                            }
                 //} // EET_MOUSE_INPUT_EVENT

                return false;
            } // end func OnEvent()



            /// теперь как этим пользоваться
            virtual bool IsKeyDown( s32 _keyCode_ ) const { return is_kStates[_keyCode_]; }

            // отслеживает только 1-разовые щелчки мыши
            virtual bool IsMouseDown( s32 _mouseCode_ ) const { return is_mStates[_mouseCode_]; }

            // а вот это и зажимание кнопки отследить может
            virtual bool IsMouseDragging( s32 _mouseCode_ )
            {
                return   ( events->MouseInput.isLeftPressed() && _mouseCode_ == EMIE_LMOUSE_PRESSED_DOWN )
                      || ( events->MouseInput.isMiddlePressed() && _mouseCode_ == EMIE_MMOUSE_PRESSED_DOWN )
                      || ( events->MouseInput.isRightPressed() && _mouseCode_ == EMIE_RMOUSE_PRESSED_DOWN );
            }

        }; // end struct

} // end namespace irr

#endif // CBASERECEIVERMODULE_H_INCLUDED
